﻿using System;
using System.Configuration;
using XieCan.AspMVC.Helpers;
using XieCan.AspMVC.IService;
using XieCan.AspMVC.Models;

namespace XieCan.AspMVC.Service
{
    public partial class AccountService : IAccountService
    {
        #region 内部支持
        private readonly string times = ConfigurationManager.AppSettings["login:maxTimes"];
        private readonly string locks = ConfigurationManager.AppSettings["login:lockTime"];

        /// <summary>
        /// 最大尝试次数，默认5
        /// </summary>
        private int Times
        {
            get
            {
                if (!int.TryParse(times, out int result))
                    result = 5;
                return result;
            }
        }

        /// <summary>
        /// 自动解锁时间（分钟），默认30
        /// </summary>
        private int Locks
        {
            get
            {
                if (!int.TryParse(locks, out int result))
                    result = 30;
                return result;
            }
        }

        /// <summary>
        /// 调整账号登录的错误计数器
        /// </summary>
        /// <param name="model">账号</param>
        /// <param name="times">错误次数</param>
        /// <returns></returns>
        private OperateResult<bool> SetErrorTimes(AccountModel model, int times)
        {
            model.ErrorTimes = times;
            model.LastTime = DateTime.Now;
            Service.Update(null, model);
            return Service.SaveChanges();
        }

        #endregion

        OperateResult<AccountModel> IAccountService.CheckAccount(AccountModel model)
        {
            var result = Service.Find(p => p.Account == model.Account);
            if (result.Success)
            {
                var user = result.Data;
                if (user == null)
                    return OperateResult<AccountModel>.Failed("账号不存在");

                return OperateResult<AccountModel>.Succeeded(user);
            }
            return OperateResult<AccountModel>.Failed(result.Error);
        }

        OperateResult<bool> IAccountService.Register(AccountModel model)
        {
            var result = Service.CheckAccount(model);
            if (result.Success)
            {
                return OperateResult<bool>.Failed($"账号{{{model.Account}}}已经存在，请换一个重试！");
            }
            model.Salt = VerifyCodeHelper.GetCodeCh(6);
            model.Password = MD5Helper.MD5Encoding(model.Password, model.Salt);
            Service.Insert(model);
            return Service.SaveChanges();
        }

        OperateResult<AccountModel> IAccountService.Login(AccountModel model)
        {
            var result = Service.CheckAccount(model);
            if (result.Success)
            {
                var user = result.Data;
                if (user.ErrorTimes >= Times)
                {
                    var minutes = (user.LastTime.Value.AddMinutes(Locks) - DateTime.Now).Minutes;
                    if (minutes > 0)
                    {
                        return OperateResult<AccountModel>.Failed($"错误次数太多，账号{{{model.Account}}}已被锁定，请您于{minutes}分钟后再次尝试！");
                    }
                    else
                    {
                        SetErrorTimes(user, 0);
                    }
                }

                var pass = MD5Helper.MD5Encoding(model.Password, user.Salt);
                if (!user.Password.Equals(pass, StringComparison.CurrentCultureIgnoreCase))
                {
                    var times = user.ErrorTimes + 1;
                    SetErrorTimes(user, times);
                    return OperateResult<AccountModel>.Failed($"密码不正确！您还有{Times - times}次机会，账号{{{model.Account}}}将被锁定");
                }

                SetErrorTimes(user, 0);
                return OperateResult<AccountModel>.Succeeded(user);
            }
            return OperateResult<AccountModel>.Failed(result.Error);
        }
    }
}
